/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package maincz.tests.webapp.security;

import java.io.IOException;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.logging.Logger;
import javax.faces.application.FacesMessage;
import javax.faces.bean.RequestScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.Size;
import maincz.tests.webapp.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.stereotype.Component;

/**
 * Beana pro logovani uzivatele.
 * @author Main
 */
@Component("loginBean")
@RequestScoped
public class LoginBean implements Serializable {

    @Size(min=1, message="Cannot be empty")
    private String username;
    @Size(min=1, message="Cannot be empty")
    private String password;
    
    @Autowired
    private IUserService userService;
    
    @Autowired
    private AuthenticationManager authenticationManager;
    
    private static final Logger log = Logger.getLogger(LoginBean.class.getName());

    public LoginBean() {
        super();
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    
    public Collection<? extends GrantedAuthority> getRoles() {
        return SecurityContextHolder.getContext().getAuthentication().getAuthorities();
    }

    /** 
     * Pokus o prihlaseni uzivatel.
     * @return 
     */
    public String login() throws IOException, ServletException {
        try {
            Authentication request = new UsernamePasswordAuthenticationToken(
                    this.username, this.password);
            Authentication result = this.authenticationManager.authenticate(request);
            SecurityContextHolder.getContext().setAuthentication(result); 
        }
        catch (AuthenticationException ex) {
            FacesContext.getCurrentInstance().addMessage(null, 
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(), ex.getMessage()));
            return null;
        }
        
        ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
        
        ((HttpServletRequest)context.getRequest()).getSession()
                .setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());
        
        FacesContext.getCurrentInstance().responseComplete();
        SavedRequest savedRequest = new HttpSessionRequestCache().getRequest(
                (HttpServletRequest)  context.getRequest(), 
                (HttpServletResponse) context.getResponse());
        
        // TODO zjistit, proc to presmerovava na nejakou divnou adresu
        //context.redirect(savedRequest.getRedirectUrl());
        context.redirect("index.xhtml");
        
        FacesContext.getCurrentInstance().responseComplete();
        
        return null;
    }
    
    /**
     * Odhlaseni uzivatele.
     * @return
     * @throws IOException 
     */
    public String logout() throws IOException {
        this.username = "";
        this.password = "";
            
        ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
        context.redirect(context.getRequestContextPath() + "/j_spring_security_logout");
        FacesContext.getCurrentInstance().responseComplete();
        return null;
    }
    
}
